home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / daten / astrolog / src / astrolog.c < prev    next >
C/C++ Source or Header  |  1995-08-11  |  44KB  |  1,797 lines

  1. /*                                                               -*- C -*-
  2. ** Astrolog (Version 4.40) File: astrolog.c
  3. **
  4. ** IMPORTANT NOTICE: The graphics database and chart display routines
  5. ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
  6. ** (astara@u.washington.edu). Permission is granted to freely use and
  7. ** distribute these routines provided one doesn't sell, restrict, or
  8. ** profit from them in any way. Modification is allowed provided these
  9. ** notices remain with any altered or edited versions of the program.
  10. **
  11. ** The main planetary calculation routines used in this program have
  12. ** been Copyrighted and the core of this program is basically a
  13. ** conversion to C of the routines created by James Neely as listed in
  14. ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  15. ** available from Matrix Software. The copyright gives us permission to
  16. ** use the routines for personal use but not to sell them or profit from
  17. ** them in any way.
  18. **
  19. ** The PostScript code within the core graphics routines are programmed
  20. ** and Copyright (C) 1992-1993 by Brian D. Willoughby
  21. ** (brianw@sounds.wa.com). Conditions are identical to those above.
  22. **
  23. ** The extended accurate ephemeris databases and formulas are from the
  24. ** calculation routines in the program "Placalc" and are programmed and
  25. ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
  26. ** (alois@azur.ch). The use of that source code is subject to
  27. ** regulations made by Astrodienst Zurich, and the code is not in the
  28. ** public domain. This copyright notice must not be changed or removed
  29. ** by any user of this program.
  30. **
  31. ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
  32. ** X Window graphics initially programmed 10/23-29/1991.
  33. ** PostScript graphics initially programmed 11/29-30/1992.
  34. ** Last code change made 1/29/1995.
  35. */
  36.  
  37. /* $VER: $Id: astrolog.c,v 1.2 1995/07/02 22:20:03 tf Exp $ */
  38.  
  39. #include "astrolog.h"
  40.  
  41. /*
  42. ******************************************************************************
  43. ** Program Dispatch Procedures.
  44. ******************************************************************************
  45. */
  46.  
  47. /* Initialize the Ansi color arrays with the color to print each object in. */
  48.  
  49. void InitColors()
  50. {
  51.   int i;
  52.  
  53.   kObjA[0] = kElemA[eEar];
  54.   for (i = 1; i <= 10; i++)
  55.     kObjA[i] = kSignA(ruler1[i]);
  56.   for (i = 11; i <= 15; i++)
  57.     kObjA[i] = kMainA[8];
  58.   for (i = 16; i <= 20; i++)
  59.     kObjA[i] = kMainA[6];
  60.   for (i = 1; i <= cSign; i++)
  61.     kObjA[cuspLo+i-1] = kSignA(i);
  62.   for (i = uranLo; i <= uranHi; i++)
  63.     kObjA[i] = kRainbowA[7];
  64.   for (i = starLo; i <= starHi; i++)
  65.     kObjA[i] = starbright[i-oNorm] < 1.0 ? kRainbowA[2] : kMainA[4];
  66. }
  67.  
  68.  
  69. /* This is the dispatch procedure for the entire program. After all the   */
  70. /* command switches have been processed, this routine is called to        */
  71. /* actually call the various routines to generate and display the charts. */
  72.  
  73. void Action()
  74. {
  75.   char sz[cchSzDef];
  76.   int i;
  77.  
  78.   is.fSzPersist = fFalse;
  79.   is.cchRow = 0;
  80.   AnsiColor(kDefault);
  81.   InitColors();
  82.  
  83.   if (fSouthNode)
  84.   {
  85.     szObjName[oSou] = "S.Node";
  86.  
  87. #ifdef INTERPRET
  88.     szMindPart[oSou] = "karmic past, and area of experience but little growth";
  89. #endif
  90.     ruler1[oSou] = sLeo;
  91.   }
  92.   if (us.fParallel) {
  93.     szAspectAbbrev[aCon] = "Par"; szAspectAbbrev[aOpp] = "CPr";
  94.   }
  95.  
  96.   /* First let's adjust the restriction status of the cusps, uranians, and */
  97.   /* fixed stars based on whether -C, -u, and -U switches are in effect.   */
  98.  
  99.   if (!us.fCusp)
  100.     for (i = cuspLo; i <= cuspHi; i++)
  101.       ignore[i] = ignore2[i] = fTrue;
  102.  
  103.   if (!us.fUranian)
  104.     for (i = uranLo; i <= uranHi; i++)
  105.       ignore[i] = ignore2[i] = fTrue;
  106.  
  107.   if (!us.nStar)
  108.     for (i = starLo; i <= starHi; i++)
  109.       ignore[i] = ignore2[i] = fTrue;
  110.  
  111.   /* If the -os switch is in effect, open a file and set a global to */
  112.   /* internally 'redirect' all screen output to.                     */
  113.  
  114.   if (is.szFileScreen) 
  115.   {
  116.     S = fopen(is.szFileScreen, "w");
  117.     if (S == NULL)  
  118.     {
  119.       sprintf(sz, "File %s can not be created.", is.szFileScreen);
  120.       PrintError(sz);
  121.       S = stdout;
  122.     }
  123.   } 
  124.   else S = stdout;
  125.  
  126.   if (FPrintTables())    /* Print out any generic tables specified.        */
  127.     return;              /* If nothing else to do, we can exit right away. */
  128.  
  129.   if (is.fMult) 
  130.   {
  131.     PrintL2();
  132.     is.fMult = fFalse;
  133.   }
  134.  
  135.   /* If -+ or -- switches in effect, then add the specified delta value to */
  136.   /* the date and use that as a new date before proceeding to make chart.  */
  137.  
  138.   if (us.dayDelta != 0) 
  139.   {
  140.     is.JD = (real)MdyToJulian(MM, DD+us.dayDelta, YY);
  141.     JulianToMdy(is.JD, &MM, &DD, &YY);
  142.   }
  143.  
  144.   /* Here we either do a normal chart or some kind of relationship chart. */
  145.  
  146.   if (!us.nRel) 
  147.   {
  148.     /* If chart info not in memory yet, then prompt the user for it. */
  149.     if (!is.fHaveInfo && !FInputData(szTtyCore))
  150.       return;
  151.  
  152.     CastChart(fTrue);
  153.     ciMain = ciCore;
  154.   }
  155.   else CastRelation(fTrue);
  156.  
  157.   ciSave = ciMain;
  158.  
  159. #ifdef GRAPH
  160.   if (us.fGraphics)         /* If any of the X window switches in effect, */
  161.     FActionX();             /* then go make a graphics chart...           */
  162.   else
  163. #endif
  164.     PrintChart(is.fProgress);    /* Otherwise print chart on text screen. */
  165.  
  166.   if (us.fWriteFile)        /* If -o switch in effect, then write */
  167.     FOutputData();          /* the chart information to a file.   */
  168.  
  169.   if (S != stdout)    /* If we were internally directing chart display to a */
  170.     fclose(S);        /* file as with the -os switch, close it here.        */
  171.  
  172.   if (grid)
  173.     DeallocateFar(grid);
  174. }
  175.  
  176.  
  177. /* Reset a few variables to their default values they have upon startup of */
  178. /* the program. We don't reset all variables, just the most volatile ones. */
  179. /* This is called when in the -Q loop to reset things like which charts to */
  180. /* display, but leave setups such as object restrictions and orbs alone.   */
  181.  
  182. void InitVariables()
  183. {
  184.   us.fInterpret = us.fProgress = is.fHaveInfo = is.fMult = fFalse;
  185.   us.nRel = us.dayDelta = 0;
  186.   is.szFileScreen = NULL;
  187.   ClearB((lpbyte)&us.fListing, (int)((lpbyte)&us.fLoop - (lpbyte)&us.fListing));
  188. }
  189.  
  190.  
  191. /*
  192. ******************************************************************************
  193. ** Command Switch Procedures.
  194. ******************************************************************************
  195. */
  196.  
  197. /* Given a string representing a command line (e.g. a macro string), go    */
  198. /* parse it into its various switches and parameters, then go process them */
  199. /* and change program settings. Basically a wrapper for other functions.   */
  200.  
  201. bool FProcessCommandLine(szLine)
  202. char *szLine;
  203. {
  204.   char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
  205.   int argc, cb, fT;
  206.  
  207.   if (szLine == NULL)
  208.     return fTrue;
  209.  
  210.   if (Mon != -1)
  211.     ciCore = ciMain;
  212.  
  213.   cb = CchSz(szLine)+1;
  214.   CopyRgb((byte *)szLine, (byte *)szCommandLine, cb);
  215.   argc = NParseCommandLine(szCommandLine, rgsz);
  216.   fT = FProcessSwitches(argc, rgsz);
  217.   ciMain = ciCore;
  218.   return fT;
  219. }
  220.  
  221.  
  222. /* Given string representing a command line, convert it to an "argv" format */
  223. /* of an array of strings, one for each switch or parameter, i.e. exactly   */
  224. /* like the format of the command line as given when the program starts.    */
  225.  
  226. int NParseCommandLine(szLine, argv)
  227. char *szLine;
  228. char **argv;
  229. {
  230.   int argc = 1, fSpace = fTrue, fQuote = fFalse;
  231.   char *pch = szLine;
  232.  
  233.   /* Split the entered line up into its individual switch strings. */
  234.   while (*pch >= ' ' || *pch == chTab) 
  235.   {
  236.     if (*pch == ' ' || *pch == chTab) 
  237.     {
  238.       if (fSpace)
  239.         /* Skip over the current run of spaces between strings. */
  240.         ;
  241.       else 
  242.       {
  243.         /* First space after a string, end parameter here. */
  244.         if (!fQuote) 
  245.         {
  246.           *pch = chNull;
  247.           fSpace = fTrue;
  248.         }
  249.       }
  250.     }
  251.  
  252.     else /* not space or tab */
  253.     {
  254.       if (fSpace)
  255.       {
  256.         /* First character after run of spaces, begin parameter here. */
  257.         if (argc >= MAXSWITCHES-1)
  258.         {
  259.           PrintWarning("Too many items - rest of line ignored.");
  260.           break;
  261.         }
  262.         fQuote = (*pch == '"');
  263.         argv[argc++] = pch + fQuote;
  264.         fSpace = fFalse;
  265.       } 
  266.       else /* Skip over the current string. */
  267.         if (fQuote && *pch == '"')
  268.         {
  269.           *pch = chNull;
  270.           fSpace = fTrue;
  271.         }
  272.     }
  273.     pch++;
  274.   }
  275.   argv[0] = szAppNameCore;
  276.   argv[argc] = NULL;         /* Set last string in switch array to Null. */
  277.   return argc;
  278. }
  279.  
  280.  
  281. /* This routine is called by the main program to interactively prompt the  */
  282. /* user for command switches and parameters, entered in the same format as */
  283. /* they would be on a command line. This needs to be called with certain   */
  284. /* systems which don't allow passing of a command line to the program,     */
  285. /* or when -Q is in effect. The result of this routine is returned to the  */
  286. /* main program which then processes it as done with a real command line.  */
  287.  
  288. int NPromptSwitches(line, argv)
  289. char *line, *argv[MAXSWITCHES];
  290. {
  291.   FILE *data;
  292.   char sz[cchSzDef];
  293.  
  294.   data = S; S = stdout;
  295.   is.cchRow = 0;
  296.  
  297.   AnsiColor(kWhite);
  298.   sprintf(sz, "** %s version %s ", szAppName, szVersionCore); PrintSz(sz);
  299.   sprintf(sz, "(See '%cHc' switch for copyrights and credits.) **\n", chSwitch); PrintSz(sz);
  300.  
  301.   AnsiColor(kDefault);
  302.   PrintSz("Enter all parameter options below. ");
  303.   sprintf(sz, "(Enter '%cH' for help. Enter '.' to exit.)\n", chSwitch);
  304.   PrintSz(sz);
  305.   S = data;
  306.   InputString("Input command line", line);
  307.   PrintL();
  308.   return NParseCommandLine(line, argv);
  309. }
  310.  
  311.  
  312. /* This subprocedure is like FProcessSwitches() below, except that we only */
  313. /* process one switch, which we know to be one of the obscure -Y types.    */
  314.  
  315. int NProcessSwitchesRare(argc, argv, pos, fOr, fAnd, fNot)
  316. int argc, pos;
  317. bool fOr, fAnd, fNot;
  318. char **argv;
  319. {
  320.   int darg = 0, i, j, k;
  321.   real r;
  322.   char ch1, ch2;
  323.   OE oe;
  324.   lpbyte lpb;
  325.   int FAR *lpn;
  326.   lpreal lpr;
  327. #ifdef INTERPRET
  328.   char *sz;
  329. #endif
  330.  
  331.   ch1 = argv[0][pos+1]; ch2 = argv[0][pos+2];
  332.  
  333.   switch (argv[0][pos]) {
  334.   case chNull:
  335.     SwitchF(us.fSwitchRare);
  336.     break;
  337.  
  338.   case 'n':
  339.     SwitchF(us.fTrueNode);
  340.     break;
  341.  
  342.   case 'd':
  343.     SwitchF(us.fEuroDate);
  344.     break;
  345.  
  346.   case 't':
  347.     SwitchF(us.fEuroTime);
  348.     break;
  349.  
  350.   case 'C':
  351.     SwitchF(us.fSmartCusp);
  352.     break;
  353.  
  354.   case '8':
  355.     SwitchF(us.fClip80);
  356.     break;
  357.  
  358.   case 'Q':
  359.     if (argc <= 1) 
  360.     {
  361.       ErrorArgc("YQ");
  362.       return tcError;
  363.     }
  364.  
  365.     i = atoi(argv[1]);
  366.  
  367.     if (i < 0)
  368.     {
  369.       ErrorValN("YQ", i);
  370.       return tcError;
  371.     }
  372.     us.nScrollRow = i;
  373.     darg++;
  374.     break;
  375.  
  376.   case 'o':
  377.     SwitchF(us.fWriteOld);
  378.     break;
  379.  
  380. #ifdef ARABIC
  381.   case 'P':
  382.     if (argc <= 1) 
  383.     {
  384.       ErrorArgc("YP");
  385.       return tcError;
  386.     }
  387.     i = atoi(argv[1]);
  388.  
  389.     if (!FBetween(i, -1, 1)) 
  390.     {
  391.       ErrorValN("YP", i);
  392.       return tcError;
  393.     }
  394.     us.nArabicNight = i;
  395.     darg++;
  396.     break;
  397. #endif
  398.  
  399.   case 'E':
  400.     if (argc <= 17) 
  401.     {
  402.       ErrorArgc("YE");
  403.       return tcError;
  404.     }
  405.     i = NParseSz(argv[1], pmObject);
  406.  
  407.     if (!FHelio(i))
  408.     {
  409.       ErrorValN("YE", i);
  410.       return tcError;
  411.     }
  412.  
  413.     oe.sma = atof(argv[2]);
  414.     oe.ec0 = atof(argv[3]);  oe.ec1 = atof(argv[4]);  oe.ec2 = atof(argv[5]);
  415.     oe.in0 = atof(argv[6]);  oe.in1 = atof(argv[7]);  oe.in2 = atof(argv[8]);
  416.     oe.ap0 = atof(argv[9]);  oe.ap1 = atof(argv[10]); oe.ap2 = atof(argv[11]);
  417.     oe.an0 = atof(argv[12]); oe.an1 = atof(argv[13]); oe.an2 = atof(argv[14]);
  418.     oe.ma0 = atof(argv[15]); oe.ma1 = atof(argv[16]); oe.ma2 = atof(argv[17]);
  419.  
  420.     rgoe[IoeFromObj(i)] = oe;
  421.     darg += 17;
  422.     break;
  423.  
  424.   case 'R':
  425.     if (argc <= 2) 
  426.     {
  427.       ErrorArgc("YR");
  428.       return tcError;
  429.     }
  430.  
  431.     i = NParseSz(argv[1], pmObject); j = NParseSz(argv[2], pmObject);
  432.  
  433.     if (ch1 == '0') 
  434.     {
  435.       ignore[0]  = i != 0;
  436.       ignore2[0] = j != 0;
  437.       darg += 2;
  438.       break;
  439.     }
  440.  
  441.     if (!FItem(i))
  442.     {
  443.       ErrorValN("YR", i);
  444.       return tcError;
  445.     }
  446.  
  447.     if (!FItem(j) || j < i) 
  448.     {
  449.       ErrorValN("YR", j);
  450.       return tcError;
  451.     }
  452.  
  453.     if (argc <= 3+j-i) 
  454.     {
  455.       ErrorArgc("YR");
  456.       return tcError;
  457.     }
  458.  
  459.     lpb = (lpbyte)((ch1 == 'T') ? ignore2 : ignore);
  460.  
  461.     for (k = i; k <= j; k++)
  462.       lpb[k] = atoi(argv[3+k-i]) != 0;
  463.  
  464.     darg += 3+j-i;
  465.     break;
  466.  
  467.   case 'A':
  468.     if (argc <= 2)
  469.     {
  470.       ErrorArgc("YA");
  471.       return tcError;
  472.     }
  473.  
  474.     k = (ch1 == 'm' || ch1 == 'd') ? pmObject : pmAspect;
  475.     i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
  476.     k = (ch1 == 'm' || ch1 == 'd') ? cObj : cAspect;
  477.  
  478.     if (!FBetween(i, 1, k))
  479.     {
  480.       ErrorValN("YA", i);
  481.       return tcError;
  482.     }
  483.  
  484.     if (!FBetween(j, 1, k) || j < i)
  485.     {
  486.       ErrorValN("YA", j);
  487.       return tcError;
  488.     }
  489.  
  490.     if (argc <= 3+j-i)
  491.     {
  492.       ErrorArgc("YA");
  493.       return tcError;
  494.     }
  495.  
  496.     lpr = (lpreal)(ch1 == 'm' ? planetorb : (ch1 == 'd' ? planetadd : aspectorb));
  497.  
  498.     for (k = i; k <= j; k++)
  499.       lpr[k] = atof(argv[3+k-i]);
  500.  
  501.     darg += 3+j-i;
  502.     break;
  503.  
  504.   case 'j':
  505.     if (argc <= 2 + 2*(ch1 == '0')) 
  506.     {
  507.       ErrorArgc("Yj");
  508.       return tcError;
  509.     }
  510.     if (ch1 == '0') 
  511.     {
  512.       objectinf[oNorm+1] = atof(argv[1]);
  513.       objectinf[oNorm+2] = atof(argv[2]);
  514.       houseinf[cSign+1]  = atof(argv[3]);
  515.       houseinf[cSign+2]  = atof(argv[4]);
  516.       darg += 4;
  517.       break;
  518.     }
  519.     k = ch1 == 'C' ? pmSign : (ch1 == 'A' ? pmAspect : pmObject);
  520.     i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
  521.     k = ch1 == 'C' ? cSign : (ch1 == 'A' ? cAspect : cObj);
  522.     if (!FBetween(i, 1, k)) {
  523.       ErrorValN("Yj", i);
  524.       return tcError;
  525.     }
  526.     if (!FBetween(j, 1, k) || j < i) 
  527.     {
  528.       ErrorValN("Yj", j);
  529.       return tcError;
  530.     }
  531.     if (argc <= 3+j-i) 
  532.     {
  533.       ErrorArgc("Yj");
  534.       return tcError;
  535.     }
  536.  
  537.     lpr = (lpreal)(ch1 == 'C' ? houseinf : (ch1 == 'A' ? aspectinf :
  538.                                            (ch1 == 'T' ? transitinf : objectinf)) );
  539.     for (k = i; k <= j; k++)
  540.       lpr[k] = atof(argv[3+k-i]);
  541.  
  542.     darg += 3+j-i;
  543.     break;
  544.  
  545. #ifdef INTERPRET
  546.   case 'I':
  547.     if (argc <= 2) 
  548.     {
  549.       ErrorArgc("YI");
  550.       return tcError;
  551.     }
  552.     i = NParseSz(argv[1], ch1 == 'A' ? pmAspect : (ch1 == chNull ? pmObject : pmSign));
  553.     j = ch1 == 'A' ? cAspect : (ch1 == chNull ? oNorm : cSign);
  554.  
  555.     if (!FBetween(i, 1, j)) 
  556.     {
  557.       ErrorValN("YI", i);
  558.       return tcError;
  559.     }
  560.  
  561.     if (ch1 == 'A' && ch2 == '0')
  562.       ch1 = '0';
  563.     sz = SzPersist(argv[2]);
  564.  
  565.     switch (ch1) {
  566.     case 'A':    szInteract[i]  = sz; break;
  567.     case '0':    szTherefore[i] = sz; break;
  568.     case chNull: szMindPart[i]  = sz; break;
  569.     case 'C':    szLifeArea[i]  = sz; break;
  570.     case 'v':    szDesire[i]    = sz; break;
  571.     default:     szDesc[i]      = sz;
  572.     }
  573.     darg += 2;
  574.     break;
  575. #endif
  576.  
  577.   case 'k':
  578.     if (argc <= 2 + 2*(ch1 == 'C')) 
  579.     {
  580.       ErrorArgc("Yk");
  581.       return tcError;
  582.     }
  583.  
  584.     if (ch1 == 'C') 
  585.     {
  586.       kElemA[eFir] = NParseSz(argv[1], pmColor) & 15;
  587.       kElemA[eEar] = NParseSz(argv[2], pmColor) & 15;
  588.       kElemA[eAir] = NParseSz(argv[3], pmColor) & 15;
  589.       kElemA[eWat] = NParseSz(argv[4], pmColor) & 15;
  590.       darg += 4;
  591.       break;
  592.     }
  593.     k = ch1 == 'A' ? pmAspect : 0;
  594.     i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
  595.     k = ch1 == 'A' ? cAspect : (ch1 == '0' ? 7 : 8);
  596.  
  597.     if (!FBetween(i, ch1 != chNull, k)) {
  598.       ErrorValN("Yk", i);
  599.       return tcError;
  600.     }
  601.  
  602.     if (!FBetween(j, ch1 != chNull, k) || j < i) {
  603.       ErrorValN("Yk", j);
  604.       return tcError;
  605.     }
  606.  
  607.     if (argc <= 3+j-i) 
  608.     {
  609.       ErrorArgc("Yk");
  610.       return tcError;
  611.     }
  612.  
  613.     lpn = (int FAR *)(ch1 == 'A' ? kAspA : (ch1 == '0' ? kRainbowA : kMainA));
  614.  
  615.     for (k = i; k <= j; k++)
  616.       lpn[k] = NParseSz(argv[3+k-i], pmColor) & 15;
  617.  
  618.     darg += 3+j-i;
  619.     break;
  620.  
  621.   case 'F':
  622.     if (argc <= 8) 
  623.     {
  624.       ErrorArgc("YF");
  625.       return tcError;
  626.     }
  627.     i = NParseSz(argv[1], pmObject);
  628.  
  629.     if (!FItem(i))
  630.     {
  631.       ErrorValN("YF", i);
  632.       return tcError;
  633.     }
  634.  
  635.     r = Mod((real)(atoi(argv[2]) + (NParseSz(argv[3], pmSign)-1)*30) + atof(argv[4])/60.0);
  636.  
  637.     if (!FCusp(i))
  638.       planet[i] = r;
  639.     else
  640.     {
  641.       j = Mod12(i-(cuspLo-1)+6);
  642.       if (FBetween(i, cuspLo-1+4, cuspLo-1+9)) {
  643.         house[i-(cuspLo-1)] = r;
  644.         house[j] = Mod(r + rDegHalf);
  645.       } else {
  646.         planet[i] = r;
  647.         planet[cuspLo-1+j] = Mod(r + rDegHalf);
  648.       }
  649.     }
  650.  
  651.     j = atoi(argv[5]);
  652.     r = (j < 0 ? -1.0 : 1.0)*((real)abs(j) + atof(argv[6])/60.0);
  653.     planetalt[i] = Mod((r + rDegQuad) * 2.0) / 2.0 - rDegQuad;
  654.     ret[i] = RFromD(atof(argv[7]));
  655.     if (i <= oNorm)
  656.       SphToRec(atof(argv[8]), planet[i], planetalt[i], &spacex[i], &spacey[i], &spacez[i]);
  657.     MM = -1;
  658.     darg += 8;
  659.     break;
  660.  
  661. #ifdef GRAPH
  662.   case 'X':
  663.     return NProcessSwitchesRareX(argc, argv, pos+1);
  664. #endif
  665.  
  666.   default:
  667.     ErrorSwitch(argv[0]);
  668.     return tcError;
  669.   }
  670.   return darg;    /* Return the value to be added to argc. */
  671. }
  672.  
  673.  
  674. /* Process a command switch line passed to the program. Read each entry in */
  675. /* the argument list and set all the program modes and charts to display.  */
  676.  
  677. bool FProcessSwitches(argc, argv)
  678. int argc;
  679. char **argv;
  680. {
  681.   int ich, i, j;
  682.   bool fNot, fOr, fAnd;
  683.   real rT;
  684.   char ch1, ch2, *pch;
  685.  
  686.   argc--; argv++;
  687.  
  688.   while (argc)
  689.   {
  690.     ch1 = argv[0][0];
  691.     fNot = fOr = fAnd = fFalse;
  692.     switch (ch1) {
  693.     case '=': fOr  = fTrue; break;
  694.     case '_': fAnd = fTrue; break;
  695.     case ':':               break;
  696.     default:  fNot = fTrue; break;
  697.     }
  698.  
  699.     ich = 1 + ( FChSwitch(argv[0][0]) ? 1:0 );    /* Leading dash? */
  700.     ch1 = argv[0][ich];
  701.     ch2 = ch1 == chNull ? chNull : argv[0][ich+1];
  702.  
  703.     /*printf("parsing `%c'... in \"%s\"\n",argv[0][ich-1],argv[0]);*/
  704.  
  705.     switch (argv[0][ich-1]) {
  706.  
  707.     case 'H':
  708.       if (ch1 == 'c')
  709.         SwitchF(us.fCredit);
  710.       else if (ch1 == 'Y')
  711.         SwitchF(us.fSwitchRare);
  712. #ifdef ISG
  713.       else if (ch1 == 'X')
  714.         SwitchF(us.fKeyGraph);
  715. #endif
  716.       else if (ch1 == 'C')
  717.         SwitchF(us.fSign);
  718.       else if (ch1 == 'O')
  719.         SwitchF(us.fObject);
  720.       else if (ch1 == 'A')
  721.         SwitchF(us.fAspect);
  722.       else if (ch1 == 'F')
  723.         SwitchF(us.fConstel);
  724.       else if (ch1 == 'S')
  725.         SwitchF(us.fOrbitData);
  726.       else if (ch1 == 'I')
  727.         SwitchF(us.fMeaning);
  728.       else if (ch1 == 'e') 
  729.       {
  730.         SwitchF(us.fCredit); SwitchF(us.fSwitch); SwitchF(us.fSwitchRare);
  731.         SwitchF(us.fKeyGraph); SwitchF(us.fSign); SwitchF(us.fObject);
  732.         SwitchF(us.fAspect); SwitchF(us.fConstel); SwitchF(us.fOrbitData);
  733.         SwitchF(us.fMeaning);
  734.       } else
  735.         SwitchF(us.fSwitch);
  736.       break;
  737.  
  738.     case 'Q':
  739.       if (ch1 == '0')
  740.         SwitchF(us.fLoopInit);
  741.       SwitchF(us.fLoop);
  742.       break;
  743.  
  744.     case 'M':
  745.       i = (ch1 == '0');
  746.       if (argc <= 1+i) {
  747.         ErrorArgc("M");
  748.         return fFalse;
  749.       }
  750.       j = atoi(argv[1]);
  751.       if (!FValidMacro(j)) {
  752.         ErrorValN("M", j);
  753.         return fFalse;
  754.       }
  755.       j--;
  756.       if (i)
  757.         szMacro[j] = SzPersist(argv[2]);
  758.       else
  759.         FProcessCommandLine(szMacro[j]);
  760.       argc -= 1+i; argv += 1+i;
  761.       break;
  762.  
  763.     case 'Y':
  764.       i = NProcessSwitchesRare(argc, argv, ich, fOr, fAnd, fNot);
  765.       if (i < 0)
  766.         return fFalse;
  767.       argc -= i; argv += i;
  768.       break;
  769.  
  770.     /* Switches which determine the type of chart to display: */
  771.  
  772.     case 'v':
  773.       if (ch1 == '0')
  774.         SwitchF(us.fVelocity);
  775.       SwitchF(us.fListing);
  776.       break;
  777.  
  778.     case 'w':
  779.       if (ch1 == '0')
  780.         SwitchF(us.fWheelReverse);
  781.       if (argc > 1 && (i = atoi(argv[1]))) {
  782.         argc--; argv++;
  783.         if (!FValidWheel(i)) {
  784.           ErrorValN("w", i);
  785.           return fFalse;
  786.         }
  787.         us.nWheelRows = i;
  788.       }
  789.       SwitchF(us.fWheel);
  790.       break;
  791.  
  792.     case 'g':
  793.       if (ch1 == '0' || ch2 == '0')
  794.         SwitchF(us.fGridConfig);
  795.       if (ch1 == 'a')
  796.         SwitchF(us.fAppSep);
  797.       else if (ch1 == 'p')
  798.         SwitchF(us.fParallel);
  799. #ifdef X11
  800.       else if (ch1 == 'e') 
  801.       {
  802.         if (argc <= 1) 
  803.         {
  804.           ErrorArgc("geometry");
  805.           return fFalse;
  806.         }
  807.         gs.xWin = atoi(argv[1]);
  808.         if (argc > 2 && (gs.yWin = atoi(argv[2]))) 
  809.         {
  810.           argc--; argv++;
  811.         } 
  812.         else
  813.           gs.yWin = gs.xWin;
  814.  
  815.         if (!FValidGraphx(gs.xWin)) 
  816.         {
  817.           ErrorValN("geometry", gs.xWin);
  818.           return fFalse;
  819.         }
  820.         if (!FValidGraphy(gs.yWin)) 
  821.         {
  822.           ErrorValN("geometry", gs.yWin);
  823.           return fFalse;
  824.         }
  825.         argc--; argv++;
  826.         break;
  827.       }
  828. #endif
  829.       SwitchF(us.fGrid);
  830.       break;
  831.  
  832.     case 'a':
  833.       SwitchF(us.fAspList);
  834.       if (ch1 == '0') 
  835.       {
  836.         SwitchF(us.fAspSummary);
  837.         ch1 = ch2;
  838.       }
  839.       if (ch1 == 'a')
  840.         SwitchF(us.fAppSep);
  841.       else if (ch1 == 'p')
  842.         SwitchF(us.fParallel);
  843.       break;
  844.  
  845.     case 'm':
  846.       if (ch1 == '0')
  847.         SwitchF(us.fMidSummary);
  848.       SwitchF(us.fMidpoint);
  849.       break;
  850.  
  851.     case 'Z':
  852.       if (ch1 == '0')
  853.         SwitchF(us.fPrimeVert);
  854.       else if (ch1 == 'd')
  855.         SwitchF(us.fHorizonSearch);
  856.       SwitchF(us.fHorizon);
  857.       break;
  858.  
  859.     case 'S':
  860.       SwitchF(us.fOrbit);
  861.       break;
  862.  
  863.     case 'j':
  864.       if (ch1 == '0')
  865.         SwitchF(us.fInfluenceSign);
  866.       SwitchF(us.fInfluence);
  867.       break;
  868.  
  869.     case 'L':
  870.       if (ch1 == '0')
  871.         SwitchF(us.fLatitudeCross);
  872.       if (argc > 1 && (i = atoi(argv[1]))) 
  873.       {
  874.         argc--; argv++;
  875.         if (i < 1 || 160%i > 0)
  876.         {
  877.           ErrorValN("L", i);
  878.           return fFalse;
  879.         }
  880.         us.nAstroGraphStep = i;
  881.       }
  882.       SwitchF(us.fAstroGraph);
  883.       break;
  884.  
  885.     case 'K':
  886.       if (ch1 == 'y')
  887.         SwitchF(us.fCalendarYear);
  888.       SwitchF(us.fCalendar);
  889.       break;
  890.  
  891.     case 'd':
  892.       if (ch1 == 'p') 
  893.       {
  894.         i = (ch2 == 'y') + 2*(ch2 == 'Y');
  895. #ifdef TIME
  896.         j = i < 2 && (argv[0][ich+i+1] == 'n');
  897. #else
  898.         j = fFalse;
  899. #endif
  900.         if (!j && argc <= 2-(i&1)) {
  901.           ErrorArgc("dp");
  902.           return fFalse;
  903.         }
  904.         is.fProgress = us.fInDayMonth = fTrue;
  905.         Dst2 = us.dstDef; Zon2 = us.zonDef;
  906.         Lon2 = us.lonDef; Lat2 = us.latDef;
  907. #ifdef TIME
  908.         if (j)
  909.           GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2-Dst2);
  910. #endif
  911.         if (i) {
  912.           Mon2 = 0;
  913.           if (!j)
  914.             Yea2 = NParseSz(argv[1], pmYea);
  915.           us.nEphemYears = i == 2 ? atoi(argv[2]) : 1;
  916.         } else {
  917.           if (!j) {
  918.             Mon2 = NParseSz(argv[1], pmMon);
  919.             Yea2 = NParseSz(argv[2], pmYea);
  920.             if (!FValidMon(Mon2)) {
  921.               ErrorValN("dp", Mon2);
  922.               return fFalse;
  923.             }
  924.           }
  925.         }
  926.         if (!FValidYea(Yea2)) 
  927.         {
  928.           ErrorValN("dp", Yea2);
  929.           return fFalse;
  930.         }
  931.         if (!j) {
  932.           i = 2-(i&1);
  933.           argc -= i; argv += i;
  934.         }
  935.       } 
  936.       else if (ch1 == 'm' || ch1 == 'y' || ch1 == 'Y') 
  937.       {
  938.         if (ch1 == 'y')
  939.           us.nEphemYears = 1;
  940.         else if (ch1 == 'Y') {
  941.           if (argc <= 1) {
  942.             ErrorArgc("dY");
  943.             return fFalse;
  944.           }
  945.           i = atoi(argv[1]);
  946.           if (i < 1) {
  947.             ErrorValN("dY", i);
  948.             return fFalse;
  949.           }
  950.           us.nEphemYears = i;
  951.         }
  952.         SwitchF(us.fInDayMonth);
  953.         Mon2 = (ch1 == 'm');
  954.       }
  955. #ifdef X11
  956.       else if (ch1 == 'i') {    /* -display switch for X */
  957.         if (argc <= 1) {
  958.           ErrorArgc("display");
  959.           return fFalse;
  960.         }
  961.         gs.szDisplay = SzPersist(argv[1]);
  962.         argc--; argv++;
  963.         break;
  964.       }
  965. #endif
  966.       else if (argc > 1 && (i = atoi(argv[1]))) {
  967.         if (!FValidDivision(i)) {
  968.           ErrorValN("d", i);
  969.           return fFalse;
  970.         }
  971.         us.nDivision = i;
  972.         argc--; argv++;
  973.       }
  974.       SwitchF(us.fInDay);
  975.       break;
  976.  
  977.     case 'D':
  978.       SwitchF(us.fInDayInf);
  979.       break;
  980.  
  981.     case 'E':
  982.       if (ch1 == 'Y' && argc <= 1) {
  983.         ErrorArgc("E");
  984.         return fFalse;
  985.       }
  986.       SwitchF(us.fEphemeris);
  987.       if (ch1 == 'y')
  988.         us.nEphemYears = us.fEphemeris ? 1 : 0;
  989.       else if (ch1 == 'Y') {
  990.         i = atoi(argv[1]);
  991.         if (i < 1) {
  992.           ErrorValN("EY", i);
  993.           return fFalse;
  994.         }
  995.         us.nEphemYears = i;
  996.       }
  997.       break;
  998.  
  999.     case 'e':
  1000.       SwitchF(us.fListing); SwitchF(us.fWheel);
  1001.       SwitchF(us.fGrid); SwitchF(us.fAspList); SwitchF(us.fMidpoint);
  1002.       SwitchF(us.fHorizon); SwitchF(us.fOrbit);
  1003.       SwitchF(us.fAstroGraph); SwitchF(us.fInfluence); SwitchF(us.fCalendar);
  1004.       SwitchF(us.fInDay); SwitchF(us.fInDayInf);
  1005.       SwitchF(us.fEphemeris);
  1006.       SwitchF(us.fGridConfig); SwitchF(us.fInfluenceSign);
  1007.       SwitchF(us.fLatitudeCross);
  1008.       break;
  1009.  
  1010.     case 't':
  1011.       SwitchF(us.fTransit);
  1012.       Zon2 = us.zonDef; Dst2 = us.dstDef; Lon2 = us.lonDef; Lat2 = us.latDef;
  1013.       if (ch1 == 'p') {
  1014.         is.fProgress = fTrue;
  1015.         ch1 = argv[0][++ich];
  1016.       }
  1017.       if( (i = (ch1 == 'y') + 2*(ch1 == 'Y')) )
  1018.         ch1 = argv[0][++ich];
  1019. #ifdef TIME
  1020.       if (ch1 == 'n') {
  1021.         GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2-Dst2);
  1022.         if (i == 1)
  1023.           Mon2 = 0;
  1024.         else if (i > 1) {
  1025.           Mon2 = -1; Day2 = NParseSz(argv[1], pmDay);
  1026.         }
  1027.         break;
  1028.       }
  1029. #endif
  1030.       if (argc <= 2 - (i & 1)) {
  1031.         ErrorArgc("t");
  1032.         return fFalse;
  1033.       }
  1034.       if (i) {
  1035.         if (i == 1)
  1036.           Mon2 = 0;
  1037.         else {
  1038.           Mon2 = -1; Day2 = NParseSz(argv[2], pmDay);
  1039.         }
  1040.       } else {
  1041.         Mon2 = NParseSz(argv[1], pmMon);
  1042.         if (!FValidMon(Mon2)) {
  1043.           ErrorValN("t", Mon2);
  1044.           return fFalse;
  1045.         }
  1046.       }
  1047.       Yea2 = NParseSz(argv[2 - (i > 0)], pmYea);
  1048.       argc -= 2 - (i & 1); argv += 2 - (i & 1);
  1049.       break;
  1050.  
  1051.     case 'T':
  1052.       SwitchF(us.fTransitInf);
  1053.       Zon2 = us.zonDef; Dst2 = us.dstDef; Lon2 = us.lonDef; Lat2 = us.latDef;
  1054.       if (ch1 == 'p') {
  1055.         is.fProgress = fTrue;
  1056.         ch1 = argv[0][++ich];
  1057.       }
  1058. #ifdef TIME
  1059.       if (ch1 == 'n') {
  1060.         GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2-Dst2);
  1061.         break;
  1062.       }
  1063. #endif
  1064.       if (argc <= 3) {
  1065.         ErrorArgc("T");
  1066.         return fFalse;
  1067.       }
  1068.       Mon2 = NParseSz(argv[1], pmMon);
  1069.       Day2 = NParseSz(argv[2], pmDay);
  1070.       Yea2 = NParseSz(argv[3], pmYea);
  1071.  
  1072.       if (!FValidMon(Mon2)) {
  1073.         ErrorValN("T", Mon2);
  1074.         return fFalse;
  1075.       } else if (!FValidDay(Day2, Mon2, Yea2)) {
  1076.         ErrorValN("T", Day2);
  1077.         return fFalse;
  1078.       } else if (!FValidYea(Yea2)) {
  1079.         ErrorValN("T", Yea2);
  1080.         return fFalse;
  1081.       }
  1082.       argc -= 3; argv += 3;
  1083.       break;
  1084.  
  1085. #ifdef ARABIC
  1086.     case 'P':
  1087.       if (argc > 1 && (i = atoi(argv[1]))) {
  1088.         argc--; argv++;
  1089.         if (!FValidPart(i)) {
  1090.           ErrorValN("P", i);
  1091.           return fFalse;
  1092.         }
  1093.         us.nArabicParts = i;
  1094.       }
  1095.       if (ch1 == 'z' || ch1 == 'n' || ch1 == 'f') {
  1096.         us.nArabic = ch1;
  1097.         ch1 = ch2;
  1098.       } else
  1099.         SwitchF(us.nArabic);
  1100.       if (ch1 == '0')
  1101.         SwitchF(us.fArabicFlip);
  1102.       break;
  1103. #endif
  1104.  
  1105. #ifdef INTERPRET
  1106.     case 'I':
  1107.       if (argc > 1 && (i = atoi(argv[1]))) {
  1108.         argc--; argv++;
  1109.         if (!FValidScreen(i)) {
  1110.           ErrorValN("I", i);
  1111.           return fFalse;
  1112.         }
  1113.         us.nScreenWidth = i;
  1114.       }
  1115.       SwitchF(us.fInterpret);
  1116.       break;
  1117. #endif
  1118.  
  1119.     /* Switches which affect how the chart parameters are obtained: */
  1120.  
  1121. #ifdef TIME
  1122.     case 'n':
  1123.       FInputData(szNowCore);
  1124.       if (ch1 == 'd')
  1125.         TT = 0.0;
  1126.       else if (ch1 == 'm') {
  1127.         DD = 1; TT = 0.0;
  1128.       } else if (ch1 == 'y') {
  1129.         MM = DD = 1; TT = 0.0;
  1130.       }
  1131.       break;
  1132. #endif
  1133.  
  1134.     case 'z':
  1135.       if (ch1 == '0') {
  1136.         if (argc <= 1 || RParseSz(argv[1], pmZon) == rLarge) {
  1137.           i = us.dstDef != 0.0;
  1138.           SwitchF(i);
  1139.           SS = us.dstDef = i ? 1.0 : 0.0;
  1140.         } else {
  1141.           SS = us.dstDef = RParseSz(argv[1], pmZon);
  1142.           if (!FValidDst(us.dstDef)) {
  1143.             ErrorValR("z0", us.dstDef);
  1144.             return fFalse;
  1145.           }
  1146.           argc--; argv++;
  1147.         }
  1148.         break;
  1149.       } else if (ch1 == 'l') {
  1150.         if (argc <= 2) {
  1151.           ErrorArgc("zl");
  1152.           return fFalse;
  1153.         }
  1154.         OO = us.lonDef = RParseSz(argv[1], pmLon);
  1155.         AA = us.latDef = RParseSz(argv[2], pmLat);
  1156.         if (!FValidLon(us.lonDef)) {
  1157.           ErrorValR("zl", us.lonDef);
  1158.           return fFalse;
  1159.         } else if (!FValidLat(us.latDef)) {
  1160.           ErrorValR("zl", us.latDef);
  1161.           return fFalse;
  1162.         }
  1163.         argc -= 2; argv += 2;
  1164.         break;
  1165.       } else if (ch1 == 't') {
  1166.         if (argc <= 1) {
  1167.           ErrorArgc("zt");
  1168.           return fFalse;
  1169.         }
  1170.         TT = RParseSz(argv[1], pmTim);
  1171.         if (!FValidTim(TT)) {
  1172.           ErrorValR("zt", TT);
  1173.           return fFalse;
  1174.         }
  1175.         argc--; argv++;
  1176.         break;
  1177.       } else if (ch1 == 'd') {
  1178.         if (argc <= 1) {
  1179.           ErrorArgc("zd");
  1180.           return fFalse;
  1181.         }
  1182.         DD = NParseSz(argv[1], pmDay);
  1183.         if (!FValidDay(DD, MM, YY)) {
  1184.           ErrorValN("zd", DD);
  1185.           return fFalse;
  1186.         }
  1187.         argc--; argv++;
  1188.         break;
  1189.       } else if (ch1 == 'i') {
  1190.         if (argc <= 2) {
  1191.           ErrorArgc("zi");
  1192.           return fFalse;
  1193.         }
  1194.         ciCore.nam = SzPersist(argv[1]);
  1195.         ciCore.loc = SzPersist(argv[2]);
  1196.         argc -= 2; argv += 2;
  1197.         break;
  1198.       }
  1199.       if (argc <= 1 || RParseSz(argv[1], pmZon) == rLarge)
  1200.         ZZ -= 1.0;
  1201.       else {
  1202.         ZZ = us.zonDef = RParseSz(argv[1], pmZon);
  1203.         if (!FValidZon(us.zonDef)) {
  1204.           ErrorValR("z", us.zonDef);
  1205.           return fFalse;
  1206.         }
  1207.         argc--; argv++;
  1208.       }
  1209.       break;
  1210.  
  1211.     case 'q':
  1212.       i = (ch1 == 'y' || ch1 == 'j') + 2*(ch1 == 'm') + 3*(ch1 == 'd') +
  1213.         4*(ch1 == chNull) + 7*(ch1 == 'a') + 8*(ch1 == 'b');
  1214.       if (argc <= i) {
  1215.         ErrorArgc("q");
  1216.         return fFalse;
  1217.       }
  1218.       is.fHaveInfo = fTrue;
  1219.       if (ch1 == 'j') {
  1220.         is.JD = atof(argv[1])+rRound;
  1221.         TT = RFract(is.JD);
  1222.         JulianToMdy(is.JD-TT, &MM, &DD, &YY);
  1223.         TT = DegToDec(TT * 24.0);
  1224.         SS = ZZ = 0.0; OO = us.lonDef; AA = us.latDef;
  1225.       } else {
  1226.         MM = i > 1 ? NParseSz(argv[1], pmMon) : 1;
  1227.         DD = i > 2 ? NParseSz(argv[2], pmDay) : 1;
  1228.         YY = NParseSz(argv[3-(i<3)-(i<2)], pmYea);
  1229.         TT = i > 3 ? RParseSz(argv[4], pmTim) : (i < 3 ? 0.0 : 12.0);
  1230.         SS = i > 7 ? RParseSz(argv[5], pmDst) : (i > 6 ? 0.0 : us.dstDef);
  1231.         ZZ = i > 6 ? RParseSz(argv[5 + (i > 7)], pmZon) : us.zonDef;
  1232.         OO = i > 6 ? RParseSz(argv[6 + (i > 7)], pmLon) : us.lonDef;
  1233.         AA = i > 6 ? RParseSz(argv[7 + (i > 7)], pmLat) : us.latDef;
  1234.         if (!FValidMon(MM)) {
  1235.           ErrorValN("q", MM);
  1236.           return fFalse;
  1237.         } else if (!FValidDay(DD, MM, YY)) {
  1238.           ErrorValN("q", DD);
  1239.           return fFalse;
  1240.         } else if (!FValidYea(YY)) {
  1241.           ErrorValN("q", YY);
  1242.           return fFalse;
  1243.         } else if (!FValidTim(TT)) {
  1244.           ErrorValR("q", TT);
  1245.           return fFalse;
  1246.         } else if (!FValidDst(SS)) {
  1247.           ErrorValR("q", SS);
  1248.           return fFalse;
  1249.         } else if (!FValidZon(ZZ)) {
  1250.           ErrorValR("a", ZZ);
  1251.           return fFalse;
  1252.         } else if (!FValidLon(OO)) {
  1253.           ErrorValR("a", OO);
  1254.           return fFalse;
  1255.         } else if (!FValidLat(AA)) {
  1256.           ErrorValR("a", AA);
  1257.           return fFalse;
  1258.         }
  1259.       }
  1260.       argc -= i; argv += i;
  1261.       break;
  1262.  
  1263.     case 'i':
  1264.       if (argc <= 1) {
  1265.         ErrorArgc("i");
  1266.         return fFalse;
  1267.       }
  1268.       if (!FInputData(argv[1]))
  1269.         return fFalse;
  1270.       argc--; argv++;
  1271.       break;
  1272.  
  1273.     case '>':
  1274.       ch1 = 's';
  1275.       /* Fall through */
  1276.  
  1277.     case 'o':
  1278.       if (argc <= 1) {
  1279.         ErrorArgc("o");
  1280.         return fFalse;
  1281.       }
  1282.       if (ch1 == 's') {
  1283.         is.szFileScreen = SzPersist(argv[1]);
  1284.         argc--; argv++;
  1285.         break;
  1286.       } else if (ch1 == '0')
  1287.         SwitchF(us.fWritePos);
  1288.       SwitchF(us.fWriteFile);
  1289.       is.szFileOut = SzPersist(argv[1]);
  1290.       if (is.fSzPersist) {
  1291.         is.rgszComment = argv;
  1292.         do {
  1293.           argc--; argv++;
  1294.           is.cszComment++;
  1295.         } while (argc > 1 && !FChSwitch(argv[1][0]));
  1296.       }
  1297.       break;
  1298.  
  1299.     /* Switches which affect what information is used in a chart: */
  1300.  
  1301.     case 'R':
  1302.       if (ch1 == 'A') {
  1303.         while (argc > 1 && (i = NParseSz(argv[1], pmAspect)))
  1304.           if (!FAspect(i)) {
  1305.             ErrorValN("RA", i);
  1306.             return fFalse;
  1307.           } else {
  1308.             aspectorb[i] = -rDegHalf;
  1309.             argc--; argv++;
  1310.           }
  1311.         break;
  1312.       }
  1313.       if (ch1 == 'T') {
  1314.         pch = (char *)ignore2;
  1315.         ch1 = argv[0][++ich];
  1316.       } else
  1317.         pch = (char *)ignore;
  1318.       if (ch1 == '0')
  1319.         for (i = 1; i <= cObj; i++)
  1320.           pch[i] = fTrue;
  1321.       else if (ch1 == '1') {
  1322.         for (i = 1; i <= cObj; i++)
  1323.           pch[i] = fFalse;
  1324.         us.fCusp = us.fUranian = us.nStar = fTrue;
  1325.       } else if (ch1 == 'C')
  1326.         for (i = cuspLo; i <= cuspHi; i++)
  1327.           SwitchF(pch[i]);
  1328.       else if (ch1 == 'u')
  1329.         for (i = uranLo; i <= uranHi; i++)
  1330.           SwitchF(pch[i]);
  1331.       else if (ch1 == 'U')
  1332.         for (i = starLo; i <= starHi; i++)
  1333.           SwitchF(pch[i]);
  1334.       else if (argc <= 1 || (!NParseSz(argv[1], pmObject))) {
  1335.         for (i = oChi; i <= oVes; i++)
  1336.           SwitchF(pch[i]);
  1337.         for (i = oLil; i <= oEP; i++)
  1338.           SwitchF(pch[i]);
  1339.       }
  1340.       while (argc > 1 && (i = NParseSz(argv[1], pmObject)))
  1341.         if (!FItem(i)) {
  1342.           ErrorValN("R", i);
  1343.           return fFalse;
  1344.         } else {
  1345.           SwitchF(pch[i]);
  1346.           argc--; argv++;
  1347.         }
  1348.       break;
  1349.  
  1350.     case 'C':
  1351.       SwitchF(us.fCusp);
  1352.       break;
  1353.  
  1354.     case 'u':
  1355.       SwitchF(us.fUranian);
  1356.       break;
  1357.  
  1358.     case 'U':
  1359.       if (ch1 == 'n' || ch1 == 'b' || ch1 == 'z' || ch1 == 'l')
  1360.         us.nStar = ch1;
  1361.       else
  1362.         SwitchF(us.nStar);
  1363.       break;
  1364.  
  1365.     case 'A':
  1366.       if (ch1 != 'o' && ch1 != 'm' && ch1 != 'd' && ch1 != 'a') {
  1367.         if (argc <= 1) {
  1368.           ErrorArgc("A");
  1369.           return fFalse;
  1370.         }
  1371.         i = NParseSz(argv[1], pmAspect);
  1372.         if (!FValidAspect(i)) {
  1373.           ErrorValN("A", i);
  1374.           return fFalse;
  1375.         }
  1376.         us.nAsp = i;
  1377.         argc--; argv++;
  1378.       } else {
  1379.         if (argc <= 2) {
  1380.           ErrorArgc("A");
  1381.           return fFalse;
  1382.         }
  1383.         i = NParseSz(argv[1], ch1 == 'o' || ch1 == 'a' ? pmAspect : pmObject);
  1384.         if (i < 1 || i > (ch1 == 'o' || ch1 == 'a' ? cAspect : oNorm)) {
  1385.           ErrorValN("A", i);
  1386.           return fFalse;
  1387.         }
  1388.         rT = RParseSz(argv[2], 0);
  1389.         if (rT < -rDegMax || rT > rDegMax) {
  1390.           ErrorValR("A", rT);
  1391.           return fFalse;
  1392.         }
  1393.         if (ch1 == 'o')
  1394.           aspectorb[i] = rT;
  1395.         else if (ch1 == 'm')
  1396.           planetorb[i] = rT;
  1397.         else if (ch1 == 'd')
  1398.           planetadd[i] = rT;
  1399.         else
  1400.           aspectangle[i] = rT;
  1401.         argc -= 2; argv += 2;
  1402.       }
  1403.       break;
  1404.  
  1405.     /* Switches which affect how a chart is computed: */
  1406.  
  1407.     case 'b':
  1408.       if (ch1 == '0')
  1409.         SwitchF(us.fSeconds);
  1410. #ifdef PLACALC
  1411.       SwitchF(us.fPlacalc);
  1412. #endif
  1413.       is.fSeconds = us.fSeconds;
  1414.       break;
  1415.  
  1416.     case 'c':
  1417.       if (argc <= 1) {
  1418.         ErrorArgc("c");
  1419.         return fFalse;
  1420.       }
  1421.       i = NParseSz(argv[1], pmSystem);
  1422.       if (!FValidSystem(i)) {
  1423.         ErrorValN("c", i);
  1424.         return fFalse;
  1425.       }
  1426.       us.nHouseSystem = i;
  1427.       argc--; argv++;
  1428.       break;
  1429.  
  1430.     case 's':
  1431.       if (argc > 1 && ((rT = atof(argv[1])) != 0.0 || FNumCh(argv[1][0]))) {
  1432.         argc--; argv++;
  1433.         us.rZodiacOffset = rT;
  1434.       }
  1435.       if (ch1 == 'r')
  1436.         SwitchF(us.fEquator);
  1437.       else if (ch1 == 'h')
  1438.         us.nDegForm = 1;
  1439.       else if (ch1 == 'd')
  1440.         us.nDegForm = 2;
  1441.       else if (ch1 == 'z')
  1442.         us.nDegForm = 0;
  1443.       else
  1444.         SwitchF(us.fSiderial);
  1445.       break;
  1446.  
  1447.     case 'h':
  1448.       if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
  1449.         argc--; argv++;
  1450.       } else
  1451.         i = 1;
  1452.       if (i < 0 || i == oMoo || !FObject(i) || i > uranHi) {
  1453.         ErrorValN("h", i);
  1454.         return fFalse;
  1455.       }
  1456.       us.objCenter = i;
  1457.       pch = szObjName[0];
  1458.       szObjName[0] = szObjName[us.objCenter];
  1459.       szObjName[us.objCenter] = pch;
  1460.       if (us.objCenter < oMoo)
  1461.         us.objCenter = 1-us.objCenter;
  1462.       break;
  1463.  
  1464.     case 'p':
  1465.       if (fAnd) {
  1466.         us.fProgress = fFalse;
  1467.         break;
  1468.       }
  1469.       if (ch1 == '0') {
  1470.         SwitchF(us.fSolarArc);
  1471.         ch1 = (argv[0][++ich]);
  1472.       }
  1473.       us.fProgress = fTrue;
  1474. #ifdef TIME
  1475.       if (ch1 == 'n') {
  1476.         GetTimeNow(&Mon, &Day, &Yea, &Tim, us.zonDef - us.dstDef);
  1477.         is.JDp = MdytszToJulian(Mon, Day, Yea, Tim, us.dstDef, us.zonDef);
  1478.         break;
  1479.       }
  1480. #endif
  1481.       if (ch1 == 'd') {
  1482.         if (argc <= 1) {
  1483.           ErrorArgc("pd");
  1484.           return fFalse;
  1485.         }
  1486.         us.rProgDay = atof(argv[1]);
  1487.         if (us.rProgDay == 0.0) {
  1488.           ErrorValR("pd", us.rProgDay);
  1489.           return fFalse;
  1490.         }
  1491.         argc--; argv++;
  1492.         break;
  1493.       }
  1494.       if (argc <= 3) {
  1495.         ErrorArgc("p");
  1496.         return fFalse;
  1497.       }
  1498.       Mon = NParseSz(argv[1], pmMon);
  1499.       Day = NParseSz(argv[2], pmDay);
  1500.       Yea = NParseSz(argv[3], pmYea);
  1501.       if (!FValidMon(Mon)) {
  1502.         ErrorValN("p", Mon);
  1503.         return fFalse;
  1504.       } else if (!FValidDay(Day, Mon, Yea)) {
  1505.         ErrorValN("p", Day);
  1506.         return fFalse;
  1507.       } else if (!FValidYea(Yea)) {
  1508.         ErrorValN("p", Yea);
  1509.         return fFalse;
  1510.       }
  1511.       is.JDp = MdytszToJulian(Mon, Day, Yea, 0.0, us.dstDef, us.zonDef);
  1512.       argc -= 3; argv += 3;
  1513.       break;
  1514.  
  1515.     case 'x':
  1516.       if (argc <= 1) {
  1517.         ErrorArgc("x");
  1518.         return fFalse;
  1519.       }
  1520.       i = atoi(argv[1]);
  1521.       if (!FValidHarmonic(i)) {
  1522.         ErrorValN("x", i);
  1523.         return fFalse;
  1524.       }
  1525.       us.nHarmonic = i;
  1526.       argc--; argv++;
  1527.       break;
  1528.  
  1529.     case '1':
  1530.       if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
  1531.         argc--; argv++;
  1532.       } else
  1533.         i = oSun;
  1534.       if (!FItem(i)) {
  1535.         ErrorValN("1", i);
  1536.         return fFalse;
  1537.       }
  1538.       us.objOnAsc = fAnd ? 0 : i;
  1539.       break;
  1540.  
  1541.     case '2':
  1542.       if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
  1543.         argc--; argv++;
  1544.       } else
  1545.         i = oSun;
  1546.       if (!FItem(i)) {
  1547.         ErrorValN("2", i);
  1548.         return fFalse;
  1549.       }
  1550.       us.objOnAsc = fAnd ? 0 : -i;
  1551.       break;
  1552.  
  1553.     case '3':
  1554.       SwitchF(us.fDecan);
  1555.       break;
  1556.  
  1557.     case 'f':
  1558.       SwitchF(us.fFlip);
  1559.       break;
  1560.  
  1561.     case 'G':
  1562.       SwitchF(us.fGeodetic);
  1563.       break;
  1564.  
  1565.     case 'F':
  1566.       if (argc <= 3) {
  1567.         ErrorArgc("F");
  1568.         return fFalse;
  1569.       }
  1570.       i = NParseSz(argv[1], pmObject);
  1571.       if (!FItem(i)) {
  1572.         ErrorValN("F", i);
  1573.         return fFalse;
  1574.       }
  1575.       force[i] = (NParseSz(argv[2], pmSign)-1.0)*30.0+DecToDeg(atof(argv[3]));
  1576.       if (force[i] < 0.0 || force[i] >= rDegMax) {
  1577.         ErrorValR("F", force[i]);
  1578.         return fFalse;
  1579.       } else
  1580.         force[i] += rDegMax;
  1581.       argc -= 3; argv += 3;
  1582.       break;
  1583.  
  1584.     case '+':
  1585.       if (argc > 1 && (i = atoi(argv[1])) != 0) {
  1586.         argc--; argv++;
  1587.       } else
  1588.         i = 1;
  1589.       us.dayDelta += i * (ch1 == 'y' ? 365 : (ch1 == 'm' ? 30 : 1));
  1590.       break;
  1591.  
  1592.     case '-': case chNull:
  1593.       if (argc > 1 && (i = atoi(argv[1])) != 0) {
  1594.         argc--; argv++;
  1595.       } else
  1596.         i = 1;
  1597.       us.dayDelta -= i * (ch1 == 'y' ? 365 : (ch1 == 'm' ? 30 : 1));
  1598.       break;
  1599.  
  1600.     /* Switches for relationship and comparison charts: */
  1601.  
  1602.     case 'r':
  1603.       if (fAnd) {
  1604.         us.nRel = 0;
  1605.         break;
  1606.       }
  1607.       i = 2 + 2*((ch1 == 'c' || ch1 == 'm') && ch2 == '0');
  1608.       if (argc <= i) {
  1609.         ErrorArgc("r");
  1610.         return fFalse;
  1611.       }
  1612.       if (ch1 == 'c')
  1613.         us.nRel = rcComposite;
  1614.       else if (ch1 == 'm')
  1615.         us.nRel = rcMidpoint;
  1616.       else if (ch1 == 'd')
  1617.         us.nRel = rcDifference;
  1618. #ifdef BIORHYTHM
  1619.       else if (ch1 == 'b')
  1620.         us.nRel = rcBiorhythm;
  1621. #endif
  1622.       else if (ch1 == '0')
  1623.         us.nRel = rcDual;
  1624.       else if (ch1 == 't')
  1625.         us.nRel = rcTransit;
  1626.       else if (ch1 == 'p') {
  1627.         us.nRel = rcProgress;
  1628.         us.fSolarArc = (ch2 == '0');
  1629.       } else
  1630.         us.nRel = rcSynastry;
  1631.       is.szFile = SzPersist(argv[1]); is.szFile2 = SzPersist(argv[2]);
  1632.       if (is.fSzInteract) {
  1633.         if (!FInputData(is.szFile2))
  1634.           return fFalse;
  1635.         ciTwin = ciCore;
  1636.         if (!FInputData(is.szFile))
  1637.           return fFalse;
  1638.       }
  1639.       if (i > 2) {
  1640.         us.nRatio1 = atoi(argv[3]);
  1641.         us.nRatio2 = atoi(argv[4]);
  1642.         if (us.nRatio1 == us.nRatio2)
  1643.           us.nRatio1 = us.nRatio2 = 1;
  1644.       }
  1645.       argc -= i; argv += i;
  1646.       break;
  1647.  
  1648. #ifdef TIME
  1649.     case 'y':
  1650.       if (argc <= 1) {
  1651.         ErrorArgc("y");
  1652.         return fFalse;
  1653.       }
  1654.       if (ch1 == 'd')
  1655.         us.nRel = rcDifference;
  1656. #ifdef BIORHYTHM
  1657.       else if (ch1 == 'b')
  1658.         us.nRel = rcBiorhythm;
  1659. #endif
  1660.       else if (ch1 == 't')
  1661.         us.nRel = rcTransit;
  1662.       else if (ch1 == 'p') {
  1663.         us.nRel = rcProgress;
  1664.         if (ch2 == '0')
  1665.           SwitchF(us.fSolarArc);
  1666.       } else
  1667.         us.nRel = rcDual;
  1668.       is.szFile = SzPersist(argv[1]); is.szFile2 = szNowCore;
  1669.       argc--; argv++;
  1670.       break;
  1671. #endif
  1672.  
  1673.     /* Switches to access graphics options: */
  1674.  
  1675.     case 'k':
  1676.       if (ch1 == '0')
  1677.         us.fAnsi = 2;
  1678.       else
  1679.         SwitchF(us.fAnsi);
  1680.       break;
  1681.  
  1682. #ifdef PCG
  1683.     case 'V':
  1684.       if (argc <= 1) {
  1685.         ErrorArgc("V");
  1686.         return fFalse;
  1687.       }
  1688.       i = atoi(argv[1]);
  1689.       if (!FValidTextrows(i)) {
  1690.         ErrorValN("V", i);
  1691.         return fFalse;
  1692.       }
  1693.       gs.nTextRows = i;
  1694.       argc--; argv++;
  1695.       break;
  1696. #endif
  1697.  
  1698. #ifdef GRAPH
  1699.     case 'X':
  1700.       i = NProcessSwitchesX(argc, argv, ich, fOr, fAnd, fNot);
  1701.       if (i < 0)
  1702.         return fFalse;
  1703.       SwitchF2(us.fGraphics);
  1704.       argc -= i; argv += i;
  1705.       break;
  1706. #endif
  1707.  
  1708.     case ';':    /* The -; switch means don't process the rest of the line. */
  1709.       return fTrue;
  1710.  
  1711.     case '@':    /* The -@ switch is just a system flag indicator no-op. */
  1712.       break;
  1713.  
  1714.     case '.':                /* "-." is usually used to exit the -Q loop. */
  1715.       Terminate(tcForce);
  1716.  
  1717.     case 'B':                /* For no useful reason, -B sounds a beep. */
  1718.       putchar(chBell);
  1719.       break;
  1720.  
  1721.     default:
  1722.       ErrorSwitch(argv[0]);
  1723.       return fFalse;
  1724.     }
  1725.     argc--; argv++;
  1726.   }
  1727.   return fTrue;
  1728. }
  1729.  
  1730.  
  1731. /*
  1732. ******************************************************************************
  1733. ** Main Program.
  1734. ******************************************************************************
  1735. */
  1736.  
  1737. #ifndef NOMAIN
  1738. /* The main program, the starting point for Astrolog, follows. This routine */
  1739. /* basically consists of a loop, inside which we read a command line, and   */
  1740. /* go process it, before actually calling a routine to do the neat stuff.   */
  1741.  
  1742. #ifdef SWITCHES
  1743. int main(argc, argv)
  1744. int argc;
  1745. char **argv;
  1746. {
  1747. #else
  1748. int main()
  1749. {
  1750.   int argc;
  1751.   char **argv;
  1752. #endif
  1753.   char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
  1754.  
  1755.   S= stdout;   /* auto-init */
  1756.  
  1757.   /* Read in info from the astrolog.dat file. */
  1758.   FProcessSwitchFile(DEFAULT_INFOFILE, NULL);
  1759.  
  1760. LBegin:
  1761. #ifdef PCG
  1762.   if (gs.nTextRows > 0) {
  1763.     PcSetTextRows(gs.nTextRows);
  1764.     neg(gs.nTextRows);
  1765.   }
  1766. #endif
  1767.   if (us.fNoSwitches) {                             /* Go prompt for    */
  1768.     argc = NPromptSwitches(szCommandLine, rgsz);    /* switches if we   */
  1769.     argv = rgsz;                                    /* don't have them. */
  1770.   }
  1771.   is.szProgName = argv[0];
  1772.   is.fSzPersist = fTrue;
  1773.   if (FProcessSwitches(argc, argv)) {
  1774.     if (!us.fNoSwitches && us.fLoopInit) {
  1775.       us.fNoSwitches = fTrue;
  1776.       goto LBegin;
  1777.     }
  1778. #ifdef PCG
  1779.     if (gs.nTextRows > 0) {
  1780.       PcSetTextRows(gs.nTextRows);
  1781.       neg(gs.nTextRows);
  1782.     }
  1783. #endif
  1784.     Action();
  1785.   }
  1786.   if (us.fLoop) {       /* If -Q in effect, loop back and get switch */
  1787.     PrintL2();          /* information for another chart to display. */
  1788.     InitVariables();
  1789.     us.fLoop = us.fNoSwitches = fTrue;
  1790.     goto LBegin;
  1791.   }
  1792.   Terminate(tcOK);    /* The only standard place to exit Astrolog is here. */
  1793. }
  1794. #endif /* NOMAIN */
  1795.  
  1796. /* astrolog.c */
  1797.